//-----------------------------------------------------------------------------
// ObjModel.fx
//-----------------------------------------------------------------------------

// Input parameters.
float4x4 View;
float4x4 Projection;
float4x4 World;

float3 Light1Position; // = float3(25,50,50);
//float3 Light1Direction = normalize(float3(0.5, 1, 1));
float3 Light1Color = float3(1.0, 1.0, 1.0);
float3 Light2Direction; // = normalize(float3(-1, -1, -1));
float3 Light2Color = float3(0.5, 0.3, 0.1);
float3 AmbientColor = float3(0.1, 0.0, 0.0);
float Shininess = 0.0; //0.2;
float SpecularPower = 0.5; // 0.5;

texture Texture;
sampler Sampler = sampler_state
{
    Texture = (Texture);
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
};


// Vertex shader input structure.
struct VS_INPUT
{
    float4 Position 	: POSITION0;
    float3 Normal 		: NORMAL0;
    float2 TexCoord 	: TEXCOORD0;
    float4 BoneIndices 	: BLENDINDICES0;
    float4 BoneWeights 	: BLENDWEIGHT0;
};


// Vertex shader output structure.
struct VS_OUTPUT
{
    float4 Position 	: POSITION0;
    float3 Lighting 	: COLOR0;
    float2 TexCoord 	: TEXCOORD0;
	
    float3 viewDirection    : TEXCOORD1;
	float3 Reflection 		: TEXCOORD2;
	
};


// Vertex shader program.
VS_OUTPUT VertexShaderFunction(VS_INPUT input)
{
    VS_OUTPUT output;
    
    // Skin the vertex position.
    float4 position = mul(input.Position, World);
    output.Position = mul(mul(position, View), Projection);

    // Skin the vertex normal, then compute lighting.
    float3 normal = normalize(mul(input.Normal, World));
	
    // calculate the light direction ( from the surface to the light ), which is not	//!!
    // normalized and is in world space
     float3 lightDirection = Light1Position - position;
	// similarly, calculate the view direction, from the eye to the surface.  not
    // normalized, in world space.
    float3 eyePosition = mul(-View._m30_m31_m32, transpose(View));
    output.viewDirection = position - eyePosition;
	output.Reflection = reflect(lightDirection, normal);

    //float3 light1 = max(dot(normal, Light1Direction), 0) * Light1Color;
    //float3 light2 = max(dot(normal, Light2Direction), 0) * Light2Color;
    float3 light1 = max(dot(normal, normalize(Light1Position)), 0) * Light1Color;
    float3 light2 = max(dot(normal, normalize(-1.0 * Light1Position)), 0) * Light2Color;

    output.Lighting = light1 + light2 + AmbientColor;

    output.TexCoord = input.TexCoord;
    
    return output;
}


// Pixel shader input structure.
struct PS_INPUT
{
    float3 Lighting : COLOR0;
    float2 TexCoord : TEXCOORD0;

    float3 viewDirection    : TEXCOORD1;		//!!
	float3 reflection		: TEXCOORD2;
};


// Pixel shader program.
float4 PixelShaderFunction(PS_INPUT input) : COLOR0
{
    input.viewDirection = normalize(input.viewDirection);
	input.reflection = normalize(input.reflection);
    // use phong to calculate specular highlights: reflect the incoming light
    // vector off the normal, and use a dot product to see how "similar"
    // the reflected vector is to the view vector.    
	float rDotV = max(dot(input.reflection, input.viewDirection), 0);
    float4 specular = Shininess * float4(input.Lighting,1) * pow(rDotV, SpecularPower);		//!!

    float4 color = tex2D(Sampler, input.TexCoord);
    color.rgb *= input.Lighting;
	
	return color;// + specular;
}


technique ObjModelTechnique
{
    pass ObjModelPass
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
